﻿Function.RegisterNamespace("Test.System.Web");

Test.System.Web.CurrentRoot=System.IO.Path.GetRoot();

[Import("../../../../Source/System.js.Web/System/Web/Dom.js")]
[Fixture]
Test.System.Web.Dom=function(){
    [Fixture]
    function ctor(){
        [Fact]
        function SetsVersionInfoFromNavigator(){
            var cleanup=false;
            if(typeof(navigator)=="undefined"){
                navigator={userAgent:"expected"};
                cleanup=true;
            }
            System.Web.Dom=new System.Web.Dom.constructor();
            var expected=navigator.userAgent;
            
            var actual=System.Web.Dom.VersionInfo;
            if(cleanup)delete navigator;
        
            Assert.Equal(expected,actual);
        }

        [Fact]
        function SetsVersionInfoFromWScriptHost(){
            var cleanup=false;
            if(typeof(WScript)=="undefined"){
                cleanup=true;
                WScript={Name:"name",Version:"version",BuildVersion:"buildversion"};
            }
            var expected=String.Format("{0} Version {1} Build {2}",WScript.Name,WScript.Version,WScript.BuildVersion);
            var navigatorMock=Mocks.GetMock(Object.Global(),"navigator",undefined);
            var actual=null;

            navigatorMock(function(){
                System.Web.Dom=new System.Web.Dom.constructor();
                actual=System.Web.Dom.VersionInfo;
                if(cleanup)delete WScript;
            });
                    
            Assert.Equal(expected,actual);
        }
    }
    
    [Fixture]
    function AppendContent(){
        [Fact]
        function ThrowsIfNodeIsOmitted(){
            var expected="System.Web.Dom.AppendContent: 'node' must be a valid Node."; 
            
            var actual=Record.Exception(function(){
                System.Web.Dom.AppendContent();
            });       
            
            Assert.Equal(expected,actual);
        }

        [Fact]
        function ThrowsIfNodeIsUndefined(){
            var expected="System.Web.Dom.AppendContent: 'node' must be a valid Node."; 
            
            var actual=Record.Exception(function(){
                System.Web.Dom.AppendContent(undefined);
            });       
            
            Assert.Equal(expected,actual);
        }

        [Fact]
        function ThrowsIfNodeIsNull(){
            var expected="System.Web.Dom.AppendContent: 'node' must be a valid Node."; 
            
            var actual=Record.Exception(function(){
                System.Web.Dom.AppendContent(null);
            });       
            
            Assert.Equal(expected,actual);
        }
        
        [Fact]
        function ThrowsIfNodeDoesNotHaveNodeTypeProperty(){
            var expected="System.Web.Dom.AppendContent: 'node' must be a valid Node."; 
            
            var actual=Record.Exception(function(){
                System.Web.Dom.AppendContent({});
            });       
            
            Assert.Equal(expected,actual);
        }

        [Fact]
        function DoesNotThrowIfNodeHasNodeTypeProperty(){
            var actual=Record.Exception(function(){
                System.Web.Dom.AppendContent({nodeType:1},"");
            });       
            
            Assert.Null(actual);
        }

        [Fact]
        function ThrowsIfContentIsOmitted(){
            var expected="System.Web.Dom.AppendContent: 'content' must be convertible to String.";        
            
            var actual=Record.Exception(function(){
                System.Web.Dom.AppendContent({nodeType:1});
            });
            
            Assert.Equal(expected,actual);
        }

        [Fact]
        function ThrowsIfContentIsUndefined(){
            var expected="System.Web.Dom.AppendContent: 'content' must be convertible to String.";        
            
            var actual=Record.Exception(function(){
                System.Web.Dom.AppendContent({nodeType:1},undefined);
            });
            
            Assert.Equal(expected,actual);
        }

        [Fact]
        function ThrowsIfContentIsNull(){
            var expected="System.Web.Dom.AppendContent: 'content' must be convertible to String.";        
            
            var actual=Record.Exception(function(){
                System.Web.Dom.AppendContent({nodeType:1},null);
            });
            
            Assert.Equal(expected,actual);
        }

        [Fact]
        function CallsToStringOnContent(){
            var targetContent={toString:function(){
                actual=true;
                return "";
            }};
            var actual=false;
        
            System.Web.Dom.AppendContent({nodeType:1},targetContent);
        
            Assert.True(actual);
        }

        [Fact]
        function AppendsContentToUndefinedInnerHTML(){
            var targetContent="content";
            var target={nodeType:1}; 
            var expected=undefined+targetContent;
            
            System.Web.Dom.AppendContent(target,targetContent);
            var actual=target.innerHTML;
            
            Assert.Equal(expected,actual);
        }

        [Fact]
        function AppendsContentToEmptyInnerHTML(){
            var expected="expected";
            var target={nodeType:1,innerHTML:""}; 
            
            System.Web.Dom.AppendContent(target,expected);
            var actual=target.innerHTML;
            
            Assert.Equal(expected,actual);
        }

        [Fact]
        function AppendsContentToExistingInnerHTML(){
            var targetContent="content";
            var target={nodeType:1,innerHTML:"innerHTML"}; 
            var expected=target.innerHTML+targetContent;
            
            System.Web.Dom.AppendContent(target,targetContent);
            var actual=target.innerHTML;
            
            Assert.Equal(expected,actual);
        }
    }

    [Fixture]
    function AppendText(){
        [Fact]
        function ThrowsIfNodeIsOmitted(){
            var expected="System.Web.Dom.AppendText: 'node' must be a valid Node."; 
            
            var actual=Record.Exception(function(){
                System.Web.Dom.AppendText();
            });       
            
            Assert.Equal(expected,actual);
        }

        [Fact]
        function ThrowsIfNodeIsUndefined(){
            var expected="System.Web.Dom.AppendText: 'node' must be a valid Node."; 
            
            var actual=Record.Exception(function(){
                System.Web.Dom.AppendText(undefined);
            });       
            
            Assert.Equal(expected,actual);
        }

        [Fact]
        function ThrowsIfNodeIsNull(){
            var expected="System.Web.Dom.AppendText: 'node' must be a valid Node."; 
            
            var actual=Record.Exception(function(){
                System.Web.Dom.AppendText(null);
            });       
            
            Assert.Equal(expected,actual);
        }
        
        [Fact]
        function ThrowsIfNodeDoesNotHaveNodeTypeProperty(){
            var expected="System.Web.Dom.AppendText: 'node' must be a valid Node."; 
            
            var actual=Record.Exception(function(){
                System.Web.Dom.AppendText({});
            });       
            
            Assert.Equal(expected,actual);
        }

        [Fact]
        function DoesNotThrowIfNodeHasNodeTypeProperty(){
            var actual=Record.Exception(function(){
                System.Web.Dom.AppendText({nodeType:1,appendChild:function(){},ownerDocument:{createTextNode:function(){}}},"");
            });       
            
            Assert.Null(actual);
        }

        [Fact]
        function ThrowsIfTextIsOmitted(){
            var expected="System.Web.Dom.AppendText: 'text' must be convertible to String.";        
            
            var actual=Record.Exception(function(){
                System.Web.Dom.AppendText({nodeType:1});
            });
            
            Assert.Equal(expected,actual);
        }

        [Fact]
        function ThrowsIfTextIsUndefined(){
            var expected="System.Web.Dom.AppendText: 'text' must be convertible to String.";        
            
            var actual=Record.Exception(function(){
                System.Web.Dom.AppendText({nodeType:1},undefined);
            });
            
            Assert.Equal(expected,actual);
        }
        
        [Fact]
        function ThrowsIfTextIsNull(){
            var expected="System.Web.Dom.AppendText: 'text' must be convertible to String.";        
            
            var actual=Record.Exception(function(){
                System.Web.Dom.AppendText({nodeType:1},null);
            });
            
            Assert.Equal(expected,actual);
        }

        [Fact]
        function CallsCreateTextNodeOnOwnerDocument(){
            var targetNode={
                nodeType:1,
                appendChild:function(){},
                ownerDocument:{
                    createTextNode:function(){
                        actual=true;
                    }
                }
            };
            var actual=false;
        
            System.Web.Dom.AppendText(targetNode,"");
        
            Assert.True(actual);
        }

        [Fact]
        function CallsAppendChildOnNode(){
            var targetNode={
                nodeType:1,
                appendChild:function(){
                    actual=true;
                },
                ownerDocument:{
                    createTextNode:function(){}
                }
            };
            var actual=false;
        
            System.Web.Dom.AppendText(targetNode,"");
        
            Assert.True(actual);
        }

        [Fact]
        function PassesResultFromCreateTextNodeToAppendChild(){
            var targetNode={
                nodeType:1,
                appendChild:function(targetExpected){
                    actual=targetExpected;
                },
                ownerDocument:{
                    createTextNode:function(){
                        return expected;
                    }
                }
            };
            var expected="expected";
            var actual=false;
        
            System.Web.Dom.AppendText(targetNode,"");
        
            Assert.Equal(expected,actual);
        }
    }
    
    [Fixture]
    function ClearContent(){
        [Fact]
        function ThrowsIfNodeIsOmitted(){
            var expected="System.Web.Dom.ClearContent: 'node' must be a valid Node."; 
            
            var actual=Record.Exception(function(){
                System.Web.Dom.ClearContent();
            });       
            
            Assert.Equal(expected,actual);
        }

        [Fact]
        function ThrowsIfNodeIsUndefined(){
            var expected="System.Web.Dom.ClearContent: 'node' must be a valid Node."; 
            
            var actual=Record.Exception(function(){
                System.Web.Dom.ClearContent(undefined);
            });       
            
            Assert.Equal(expected,actual);
        }

        [Fact]
        function ThrowsIfNodeIsNull(){
            var expected="System.Web.Dom.ClearContent: 'node' must be a valid Node."; 
            
            var actual=Record.Exception(function(){
                System.Web.Dom.ClearContent(null);
            });       
            
            Assert.Equal(expected,actual);
        }
        
        [Fact]
        function ThrowsIfNodeDoesNotHaveNodeTypeProperty(){
            var expected="System.Web.Dom.ClearContent: 'node' must be a valid Node."; 
            
            var actual=Record.Exception(function(){
                System.Web.Dom.ClearContent({});
            });       
            
            Assert.Equal(expected,actual);
        }

        [Fact]
        function DoesNotThrowIfNodeHasNodeTypeProperty(){
            var actual=Record.Exception(function(){
                System.Web.Dom.ClearContent({nodeType:1},"");
            });       
            
            Assert.Null(actual);
        }
        
        [Fact]
        function SetsUndefinedInnerHTMLToEmptyString(){
            var targetNode={nodeType:1};
            var expected="";
            
            System.Web.Dom.ClearContent(targetNode);
            var actual=targetNode.innerHTML;
        
            Assert.Equal(expected,actual);
        }

        [Fact]
        function SetsExistingInnerHTMLToEmptyString(){
            var targetNode={nodeType:1,innerHTML:"Inner HTML."};
            var expected="";
            
            System.Web.Dom.ClearContent(targetNode);
            var actual=targetNode.innerHTML;
        
            Assert.Equal(expected,actual);
        }
    }
    
    [Fixture]
    function CreateElement(){
        [Fact]
        function DoesNotThrowIfOwnerDocumentIsOmitted(){
            var cleanup=false;
            if(typeof(document)=="undefined"){
                document={createElement:function(){}};
                cleanup=true;
            }
            
            var actual=Record.Exception(function(){
                System.Web.Dom.CreateElement(null,null,null);
            });
            if(cleanup)delete document;
            
            Assert.Null(actual);
        }
        
        [Fact]
        function ThrowsIfOwnerDocumentIsUndefined(){
            var expected="System.Web.Dom.CreateElement: 'ownerDocument' must be a valid Object.";

            var actual=Record.Exception(function(){
                System.Web.Dom.CreateElement(null,null,null,undefined);
            });
            
            Assert.Equal(expected,actual);
        }

        [Fact]
        function ThrowsIfOwnerDocumentIsNull(){
            var expected="System.Web.Dom.CreateElement: 'ownerDocument' must be a valid Object.";
            
            var actual=Record.Exception(function(){
                System.Web.Dom.CreateElement(null,null,null,null);
            });
            
            Assert.Equal(expected,actual);
        }
        
        [Fact]
        function ThrowsIfOwnerDocumentDoesNotImplementCreateElement(){
            var expected="System.Web.Dom.CreateElement: 'ownerDocument' does not implement method 'createElement(tagName)'.";
            
            var actual=Record.Exception(function(){
                System.Web.Dom.CreateElement(null,null,null,{});
            });
            
            Assert.Equal(expected,actual);
        }
    
        [Fact]
        function CallsCreateElementOnOwnerDocument(){
            var targetDocument={createElement:function(){
                actual=true;
            }}            
            var actual=false;

            System.Web.Dom.CreateElement(null,null,null,targetDocument);
            
            Assert.True(actual);
        }

        [Fact]
        function PassesDivToCreateElementOnOwnerDocumentIfTagNameIsUndefined(){
            var targetDocument={createElement:function(targetExpected){
                actual=targetExpected;
            }}
            var expected="div";        
            var actual=null;

            System.Web.Dom.CreateElement(null,null,undefined,targetDocument);

            Assert.Equal(expected,actual);
        }

        [Fact]
        function PassesDivToCreateElementOnOwnerDocumentIfTagNameIsNull(){
            var targetDocument={createElement:function(targetExpected){
                actual=targetExpected;
            }}
            var expected="div";        
            var actual=null;

            System.Web.Dom.CreateElement(null,null,null,targetDocument);

            Assert.Equal(expected,actual);
        }

        [Fact]
        function PassesDivToCreateElementOnOwnerDocumentIfTagNameIsStringEmpty(){
            var targetDocument={createElement:function(targetExpected){
                actual=targetExpected;
            }}
            var expected="div";        
            var actual=null;

            System.Web.Dom.CreateElement(null,null,'',targetDocument);

            Assert.Equal(expected,actual);
        }

        [Fact]
        function PassesDivToCreateElementOnOwnerDocumentIfTagNameIsBooleanFalse(){
            var targetDocument={createElement:function(targetExpected){
                actual=targetExpected;
            }}
            var expected="div";        
            var actual=null;

            System.Web.Dom.CreateElement(null,null,false,targetDocument);

            Assert.Equal(expected,actual);
        }

        [Fact]
        function PassesDivToCreateElementOnOwnerDocumentIfTagNameIsNumberZero(){
            var targetDocument={createElement:function(targetExpected){
                actual=targetExpected;
            }}
            var expected="div";        
            var actual=null;

            System.Web.Dom.CreateElement(null,null,0,targetDocument);

            Assert.Equal(expected,actual);
        }

        [Fact]
        function PassesTagNameToCreateElementOnOwnerDocument(){
            var targetDocument={createElement:function(targetExpected){
                actual=targetExpected;
            }}
            var expected="expected";        
            var actual=null;

            System.Web.Dom.CreateElement(null,null,expected,targetDocument);

            Assert.Equal(expected,actual);
        }

        [Fact]
        function CallsCreateElementOnGlobalDocumentIfOwnerDocumentOmitted(){
            var cleanup=false;
            if(typeof(document)=="undefined"){
                document={};
                cleanup=true;
            }
            var targetCreateElement=document.createElement;
            document.createElement=function(){
                actual=true;
            };
            var actual=false;

            System.Web.Dom.CreateElement(null,null,null);
            document.createElement=targetCreateElement;
            if(cleanup)delete document;

            Assert.True(actual);
        }

        [Fact]
        function PassesDivToCreateElementOnGlobalDocumentIfTagNameIsOmitted(){
            var cleanup=false;
            if(typeof(document)=="undefined"){
                document={};
                cleanup=true;
            }
            var targetCreateElement=document.createElement;
            document.createElement=function(targetExpected){
                actual=targetExpected;
            };
            var expected="div";
            var actual=null;

            System.Web.Dom.CreateElement(null,null);
            document.createElement=targetCreateElement;
            if(cleanup)delete document;

            Assert.Equal(expected,actual);
        }

        [Fact]
        function PassesDivToCreateElementOnGlobalDocumentIfTagNameIsUndefined(){
            var cleanup=false;
            if(typeof(document)=="undefined"){
                document={};
                cleanup=true;
            }
            var targetCreateElement=document.createElement;
            document.createElement=function(targetExpected){
                actual=targetExpected;
            };
            var expected="div";
            var actual=null;

            System.Web.Dom.CreateElement(null,null,undefined);
            document.createElement=targetCreateElement;
            if(cleanup)delete document;

            Assert.Equal(expected,actual);
        }

        [Fact]
        function PassesDivToCreateElementOnGlobalDocumentIfTagNameIsNull(){
            var cleanup=false;
            if(typeof(document)=="undefined"){
                document={};
                cleanup=true;
            }
            var targetCreateElement=document.createElement;
            document.createElement=function(targetExpected){
                actual=targetExpected;
            };
            var expected="div";
            var actual=null;

            System.Web.Dom.CreateElement(null,null,null);
            document.createElement=targetCreateElement;
            if(cleanup)delete document;

            Assert.Equal(expected,actual);
        }

        [Fact]
        function PassesDivToCreateElementOnGlobalDocumentIfTagNameIsBooleanFalse(){
            var cleanup=false;
            if(typeof(document)=="undefined"){
                document={};
                cleanup=true;
            }
            var targetCreateElement=document.createElement;
            document.createElement=function(targetExpected){
                actual=targetExpected;
            };
            var expected="div";
            var actual=null;

            System.Web.Dom.CreateElement(null,null,false);
            document.createElement=targetCreateElement;
            if(cleanup)delete document;

            Assert.Equal(expected,actual);
        }

        [Fact]
        function PassesDivToCreateElementOnGlobalDocumentIfTagNameIsNumberZero(){
            var cleanup=false;
            if(typeof(document)=="undefined"){
                document={};
                cleanup=true;
            }
            var targetCreateElement=document.createElement;
            document.createElement=function(targetExpected){
                actual=targetExpected;
            };
            var expected="div";
            var actual=null;

            System.Web.Dom.CreateElement(null,null,0);
            document.createElement=targetCreateElement;
            if(cleanup)delete document;

            Assert.Equal(expected,actual);
        }

        [Fact]
        function PassesDivToCreateElementOnGlobalDocumentIfTagNameIsStringEmpty(){
            var cleanup=false;
            if(typeof(document)=="undefined"){
                document={};
                cleanup=true;
            }
            var targetCreateElement=document.createElement;
            document.createElement=function(targetExpected){
                actual=targetExpected;
            };
            var expected="div";
            var actual=null;

            System.Web.Dom.CreateElement(null,null,'');
            document.createElement=targetCreateElement;
            if(cleanup)delete document;

            Assert.Equal(expected,actual);
        }

        [Fact]
        function PassesTagNameToCreateElementOnGlobalDocument(){
            var cleanup=false;
            if(typeof(document)=="undefined"){
                document={};
                cleanup=true;
            }
            var targetCreateElement=document.createElement;
            document.createElement=function(targetExpected){
                actual=targetExpected;
            };
            var expected="expected";
            var actual=null;

            System.Web.Dom.CreateElement(null,null,expected);
            document.createElement=targetCreateElement;
            if(cleanup)delete document;

            Assert.Equal(expected,actual);
        }
        
        [Fact]
        function SetsPropertyOnNodeReturned(){
            var targetDocument={createElement:function(){
                return {};
            }}
            var expected={propertyOne:"propertyOne"};
            
            var actual=System.Web.Dom.CreateElement(null,expected,null,targetDocument);
            
            Assert.Equal(expected,actual);
        }

        [Fact]
        function SetsMultiplePropertiesOnNodeReturned(){
            var targetDocument={createElement:function(){
                return {};
            }}
            var expected={propertyOne:"propertyOne",propertyTwo:"propertyTwo"};
            
            var actual=System.Web.Dom.CreateElement(null,expected,null,targetDocument);
            
            Assert.Equal(expected,actual);
        }

        [Fact]
        function SetsNestedPropertyOnNodeReturned(){
            var targetDocument={createElement:function(){
                return {};
            }}
            var expected={propertyOne:{propertyTwo:"propertyTwo"}};
            
            var actual=System.Web.Dom.CreateElement(null,expected,null,targetDocument);
            
            Assert.Equal(expected,actual);
        }
        
        [Fact]
        function DoesNotThrowIfParentNodeIsOmitted(){
            var cleanup=false;
            if(typeof(document)=="undefined"){
                document={createElement:function(){}};
                cleanup=true;
            }

            var actual=Record.Exception(function(){
                System.Web.Dom.CreateElement();
            });
            if(cleanup)delete document;
            
            Assert.Null(actual);
        }

        [Fact]
        function DoesNotThrowIfParentNodeIsUndefined(){
            var cleanup=false;
            if(typeof(document)=="undefined"){
                document={createElement:function(){}};
                cleanup=true;
            }

            var actual=Record.Exception(function(){
                System.Web.Dom.CreateElement(undefined);
            });
            if(cleanup)delete document;
            
            Assert.Null(actual);
        }

        [Fact]
        function DoesNotThrowIfParentNodeIsNull(){
            var cleanup=false;
            if(typeof(document)=="undefined"){
                document={createElement:function(){}};
                cleanup=true;
            }

            var actual=Record.Exception(function(){
                System.Web.Dom.CreateElement(null);
            });
            if(cleanup)delete document;
            
            Assert.Null(actual);
        }

        [Fact]
        function ThrowsIfParentNodeDoesNotImplementAppendChild(){
            var cleanup=false;
            if(typeof(document)=="undefined"){
                document={createElement:function(){}};
                cleanup=true;
            }
            var expected="System.Web.Dom.CreateElement: 'parentNode' does not implement method 'appendChild(node)'.";
            
            var actual=Record.Exception(function(){
                System.Web.Dom.CreateElement({});
            });
            if(cleanup)delete document;
            
            Assert.Equal(expected,actual);
        }
        
        [Fact]
        function DoesNotThrowIfParentNodeImplementsAppendChild(){
            var cleanup=false;
            if(typeof(document)=="undefined"){
                document={createElement:function(){}};
                cleanup=true;
            }
            
            var actual=Record.Exception(function(){
                System.Web.Dom.CreateElement({appendChild:function(){}});
            });
            if(cleanup)delete document;
            
            Assert.Null(actual);
        }

        [Fact]
        function CallsAppendChildOnParentNode(){
            var cleanup=false;
            if(typeof(document)=="undefined"){
                document={createElement:function(){}};
                cleanup=true;
            }
            var targetParentNode={
                appendChild:function(){
                    actual=true;
                }
            };
            var actual=false;
            
            System.Web.Dom.CreateElement(targetParentNode);
            if(cleanup)delete document;
            
            Assert.True(actual);
        }

        [Fact]
        function PassesNodeFromCreateElementToAppendChildOnParentNode(){
            var cleanup=false;
            if(typeof(document)=="undefined"){
                document={};
                cleanup=true;
            }
            var targetCreateElement=document.createElement;
            document.createElement=function(){
                return expected;
            }
            var expected={propertyOne:"propertyOne"};
            var targetParentNode={
                appendChild:function(targetNode){
                    actual=targetNode;
                }
            };
            var actual=null;
            
            System.Web.Dom.CreateElement(targetParentNode);
            document.createElement=targetCreateElement;
            if(cleanup)delete document;
            
            Assert.Equal(expected,actual);
        }
        
        [Fact]
        function ReturnsNodeFromCreateElement(){
            var cleanup=false;
            if(typeof(document)=="undefined"){
                document={};
                cleanup=true;
            }
            var targetCreateElement=document.createElement;
            document.createElement=function(){
                return expected;
            }
            var expected={propertyOne:"propertyOne"};
            
            var actual=System.Web.Dom.CreateElement();
            document.createElement=targetCreateElement;
            if(cleanup)delete document;
            
            Assert.Equal(expected,actual);
        }
    }
    
    [Fixture]
    function Decode(){
        [Fact]
        function CallsCreateElementIfContainerIsOmitted(){
            var targetCreateElement=System.Web.Dom.CreateElement;
            System.Web.Dom.CreateElement=function(){
                actual=true;
                return {nodeType:1};
            }
            var actual=false;
            
            System.Web.Dom.Decode("");
            System.Web.Dom.CreateElement=targetCreateElement;
            
            Assert.True(actual);
        }

        [Fact]
        function CallsCreateElementIfContainerIsUndefined(){
            var targetCreateElement=System.Web.Dom.CreateElement;
            System.Web.Dom.CreateElement=function(){
                actual=true;
                return {nodeType:1};
            }
            var actual=false;
            
            System.Web.Dom.Decode("",undefined);
            System.Web.Dom.CreateElement=targetCreateElement;
            
            Assert.True(actual);
        }

        [Fact]
        function CallsCreateElementIfContainerIsNull(){
            var targetCreateElement=System.Web.Dom.CreateElement;
            System.Web.Dom.CreateElement=function(){
                actual=true;
                return {nodeType:1};
            }
            var actual=false;
            
            System.Web.Dom.Decode("",null);
            System.Web.Dom.CreateElement=targetCreateElement;
            
            Assert.True(actual);
        }
        
        [Fact]
        function DoesNotCallCreateElementIfContainerIsSpecified(){
            var targetCreateElement=System.Web.Dom.CreateElement;
            System.Web.Dom.CreateElement=function(){
                actual=true;
                return {nodeType:1};
            }
            var actual=false;
            
            System.Web.Dom.Decode("",{nodeType:1});
            System.Web.Dom.CreateElement=targetCreateElement;
            
            Assert.False(actual);
        }
        
        [Fact]
        function CallsSetContent(){
            var targetSetContent=System.Web.Dom.SetContent;
            System.Web.Dom.SetContent=function(){
                actual=true;
            }
            var actual=false;
            
            System.Web.Dom.Decode("",{nodeType:1});
            System.Web.Dom.SetContent=targetSetContent;
            
            Assert.True(actual);
        }

        [Fact]
        function PassesContainerToSetContent(){
            var targetSetContent=System.Web.Dom.SetContent;
            System.Web.Dom.SetContent=function(targetContainer){
                actual=targetContainer;
            }
            var expected={nodeType:1};
            var actual=null;
            
            System.Web.Dom.Decode("",expected);
            System.Web.Dom.SetContent=targetSetContent;
            
            Assert.Equal(expected,actual);
        }

        [Fact]
        function PassesMarkupToSetContent(){
            var targetSetContent=System.Web.Dom.SetContent;
            System.Web.Dom.SetContent=function(container,targetMarkup){
                actual=targetMarkup;
            }
            var expected="markup";
            var actual=null;
            
            System.Web.Dom.Decode(expected,{nodeType:1});
            System.Web.Dom.SetContent=targetSetContent;
            
            Assert.Equal(expected,actual);
        }
        
        [Fact]
        function CallsGetText(){
            var targetGetText=System.Web.Dom.GetText;
            System.Web.Dom.GetText=function(){
                actual=true;
            }
            var actual=false;
            
            System.Web.Dom.Decode("",{nodeType:1});
            System.Web.Dom.GetText=targetGetText;
        
            Assert.True(actual);
        }
        
        [Fact]
        function PassesContainerToGetText(){
            var targetGetText=System.Web.Dom.GetText;
            System.Web.Dom.GetText=function(targetContainer){
                actual=targetContainer;
            }
            var expected={nodeType:1};
            var actual=null;
            
            System.Web.Dom.Decode("",expected);
            System.Web.Dom.GetText=targetGetText;
        
            Assert.Equal(expected,actual);
        }
        
        [Fact]
        function ReturnsResultOfGetText(){
            var targetGetText=System.Web.Dom.GetText;
            System.Web.Dom.GetText=function(){
                return expected;
            }
            var expected="expected";
            
            var actual=System.Web.Dom.Decode("",{nodeType:1});
            System.Web.Dom.GetText=targetGetText;
        
            Assert.Equal(expected,actual);
        }
    }
    
    [Fixture]
    function Encode(){
        [Fact]
        function CallsCreateElementIfContainerIsOmitted(){
            var targetCreateElement=System.Web.Dom.CreateElement;
            System.Web.Dom.CreateElement=function(){
                actual=true;
                return {nodeType:1,appendChild:function(){},ownerDocument:{createTextNode:function(){}}};
            }
            var actual=false;
            
            System.Web.Dom.Encode("");
            System.Web.Dom.CreateElement=targetCreateElement;
            
            Assert.True(actual);
        }

        [Fact]
        function CallsCreateElementIfContainerIsUndefined(){
            var targetCreateElement=System.Web.Dom.CreateElement;
            System.Web.Dom.CreateElement=function(){
                actual=true;
                return {nodeType:1,appendChild:function(){},ownerDocument:{createTextNode:function(){}}};
            }
            var actual=false;
            
            System.Web.Dom.Encode("",undefined);
            System.Web.Dom.CreateElement=targetCreateElement;
            
            Assert.True(actual);
        }

        [Fact]
        function CallsCreateElementIfContainerIsNull(){
            var targetCreateElement=System.Web.Dom.CreateElement;
            System.Web.Dom.CreateElement=function(){
                actual=true;
                return {nodeType:1,appendChild:function(){},ownerDocument:{createTextNode:function(){}}};
            }
            var actual=false;
            
            System.Web.Dom.Encode("",null);
            System.Web.Dom.CreateElement=targetCreateElement;
            
            Assert.True(actual);
        }
        
        [Fact]
        function DoesNotCallCreateElementIfContainerIsSpecified(){
            var targetCreateElement=System.Web.Dom.CreateElement;
            System.Web.Dom.CreateElement=function(){
                actual=true;
            }
            var actual=false;
            
            System.Web.Dom.Encode("",{nodeType:1,appendChild:function(){},ownerDocument:{createTextNode:function(){}}});
            System.Web.Dom.CreateElement=targetCreateElement;
            
            Assert.False(actual);
        }
        
        [Fact]
        function CallsSetText(){
            var targetSetText=System.Web.Dom.SetText;
            System.Web.Dom.SetText=function(){
                actual=true;
            }
            var actual=false;
            
            System.Web.Dom.Encode("",{nodeType:1,appendChild:function(){},ownerDocument:{createTextNode:function(){}}});
            System.Web.Dom.SetText=targetSetText;
            
            Assert.True(actual);
        }

        [Fact]
        function PassesContainerToSetText(){
            var targetSetText=System.Web.Dom.SetText;
            System.Web.Dom.SetText=function(targetContainer){
                actual=targetContainer;
            }
            var expected={nodeType:1,appendChild:function(){},ownerDocument:{createTextNode:function(){}}};
            var actual=null;
            
            System.Web.Dom.Encode("",expected);
            System.Web.Dom.SetText=targetSetText;
            
            Assert.Equal(expected,actual);
        }

        [Fact]
        function PassesTextToSetText(){
            var targetSetText=System.Web.Dom.SetText;
            System.Web.Dom.SetText=function(container,targetText){
                actual=targetText;
            }
            var expected="markup";
            var actual=null;
            
            System.Web.Dom.Encode(expected,{nodeType:1,appendChild:function(){},ownerDocument:{createTextNode:function(){}}});
            System.Web.Dom.SetText=targetSetText;
            
            Assert.Equal(expected,actual);
        }
        
        [Fact]
        function CallsGetContent(){
            var targetGetContent=System.Web.Dom.GetContent;
            System.Web.Dom.GetContent=function(){
                actual=true;
            }
            var actual=false;
            
            System.Web.Dom.Encode("",{nodeType:1,appendChild:function(){},ownerDocument:{createTextNode:function(){}}});
            System.Web.Dom.GetContent=targetGetContent;
        
            Assert.True(actual);
        }
        
        [Fact]
        function PassesContainerToGetContent(){
            var targetGetContent=System.Web.Dom.GetContent;
            System.Web.Dom.GetContent=function(targetContainer){
                actual=targetContainer;
            }
            var expected={nodeType:1,appendChild:function(){},ownerDocument:{createTextNode:function(){}}};
            var actual=null;
            
            System.Web.Dom.Encode("",expected);
            System.Web.Dom.GetContent=targetGetContent;
        
            Assert.Equal(expected,actual);
        }
        
        [Fact]
        function ReturnsResultOfGetContent(){
            var targetGetContent=System.Web.Dom.GetContent;
            System.Web.Dom.GetContent=function(){
                return expected;
            }
            var expected="expected";
            
            var actual=System.Web.Dom.Encode("",{nodeType:1,appendChild:function(){},ownerDocument:{createTextNode:function(){}}});
            System.Web.Dom.GetContent=targetGetContent;
        
            Assert.Equal(expected,actual);
        }    
    }
    
    [Fixture]
    function Focus(){
        [Fact]
        function ThrowsIfNodeIsOmitted(){
            var expected="System.Web.Dom.Focus: 'node' must be a valid Node.";
            
            var actual=Record.Exception(function(){
                System.Web.Dom.Focus();
            });
            
            Assert.Equal(expected,actual);
        }
 
        [Fact]
        function ThrowsIfNodeIsUndefined(){
            var expected="System.Web.Dom.Focus: 'node' must be a valid Node.";
            
            var actual=Record.Exception(function(){
                System.Web.Dom.Focus(undefined);
            });
            
            Assert.Equal(expected,actual);
        }
        [Fact]
        function ThrowsIfNodeIsNull(){
            var expected="System.Web.Dom.Focus: 'node' must be a valid Node.";
            
            var actual=Record.Exception(function(){
                System.Web.Dom.Focus(null);
            });
            
            Assert.Equal(expected,actual);
        }
        
        [Fact]
        function ThrowsIfNodeDoesNotImplementNodeType(){
            var expected="System.Web.Dom.Focus: 'node' must be a valid Node.";
            
            var actual=Record.Exception(function(){
                System.Web.Dom.Focus({});
            });
            
            Assert.Equal(expected,actual);
        }

        [Fact]
        function ThrowsIfNodeTypeIsBooleanFalse(){
            var expected="System.Web.Dom.Focus: 'node' must be a valid Node.";
            
            var actual=Record.Exception(function(){
                System.Web.Dom.Focus({nodeType:false});
            });
            
            Assert.Equal(expected,actual);
        }

        [Fact]
        function ThrowsIfNodeTypeIsNumberZero(){
            var expected="System.Web.Dom.Focus: 'node' must be a valid Node.";
            
            var actual=Record.Exception(function(){
                System.Web.Dom.Focus({nodeType:0});
            });
            
            Assert.Equal(expected,actual);
        }

        [Fact]
        function ThrowsIfNodeTypeIsStringEmpty(){
            var expected="System.Web.Dom.Focus: 'node' must be a valid Node.";
            
            var actual=Record.Exception(function(){
                System.Web.Dom.Focus({nodeType:''});
            });
            
            Assert.Equal(expected,actual);
        }
        
        [Fact]
        function DoesNotThrowIfNodeImplementsNodeType(){
            var actual=Record.Exception(function(){
                System.Web.Dom.Focus({nodeType:1});
            });
            
            Assert.Null(actual);
        }
        
        [Fact]
        function DoesNotThrowIfNodeDoesNotImplementSelect(){
            var actual=Record.Exception(function(){
                System.Web.Dom.Focus({nodeType:1});
            });
            
            Assert.Null(actual,true);
        }

        [Fact]
        function CallsSelectIfSelectIsSpecifiedAndNodeImplementsSelect(){
            var targetNode={nodeType:1,select:function(){
                actual=true;
            }}
            var actual=false;
            
            System.Web.Dom.Focus(targetNode,true);
            
            Assert.True(actual);
        }

        [Fact]
        function ReturnsTrueIfSelectDoesNotThrow(){
            var targetNode={nodeType:1,select:function(){}}

            var actual=System.Web.Dom.Focus(targetNode,true);
            
            Assert.True(actual);
        }

        [Fact]
        function CallsFocusIfSelectIsOmitted(){
            var targetNode={nodeType:1,focus:function(){
                actual=true;
            }}
            var actual=false;
            
            System.Web.Dom.Focus(targetNode);
            
            Assert.True(actual);
        }

        [Fact]
        function CallsFocusIfSelectIsUndefined(){
            var targetNode={nodeType:1,focus:function(){
                actual=true;
            }}
            var actual=false;
            
            System.Web.Dom.Focus(targetNode,undefined);
            
            Assert.True(actual);
        }

        [Fact]
        function CallsFocusIfSelectIsNull(){
            var targetNode={nodeType:1,focus:function(){
                actual=true;
            }}
            var actual=false;
            
            System.Web.Dom.Focus(targetNode,null);
            
            Assert.True(actual);
        }

        [Fact]
        function CallsFocusIfSelectIsBooleanFalse(){
            var targetNode={nodeType:1,focus:function(){
                actual=true;
            }}
            var actual=false;
            
            System.Web.Dom.Focus(targetNode,false);
            
            Assert.True(actual);
        }

        [Fact]
        function CallsFocusIfSelectIsNumberZero(){
            var targetNode={nodeType:1,focus:function(){
                actual=true;
            }}
            var actual=false;
            
            System.Web.Dom.Focus(targetNode,0);
            
            Assert.True(actual);
        }

        [Fact]
        function CallsFocusIfSelectIsEmptyString(){
            var targetNode={nodeType:1,focus:function(){
                actual=true;
            }}
            var actual=false;
            
            System.Web.Dom.Focus(targetNode,'');
            
            Assert.True(actual);
        }

        [Fact]
        function CallsFocusIfSelectIsNotImplemented(){
            var targetNode={nodeType:1,focus:function(){
                actual=true;
            }}
            var actual=false;
            
            System.Web.Dom.Focus(targetNode,true);
            
            Assert.True(actual);
        }
        
        [Fact]
        function ReturnsTrueIfFocusDoesNotThrow(){
            var targetNode={nodeType:1,focus:function(){}}
            
            var actual=System.Web.Dom.Focus(targetNode);
            
            Assert.True(actual);
        }
        
        [Fact]
        function SuppressesErrorIfSelectIsNotAValidFunction(){
            var targetNode={nodeType:1,select:{}}
            
            var actual=Record.Exception(function(){
                System.Web.Dom.Focus(targetNode,true);
            });
            
            Assert.Null(actual);
        }

        [Fact]
        function ReturnsFalseIfSelectIsNotAValidFunction(){
            var targetNode={nodeType:1,select:{}};
            
            var actual=System.Web.Dom.Focus(targetNode,true);
            
            Assert.False(actual);
        }        

        [Fact]
        function SuppressesErrorThrownBySelect(){
            var targetNode={nodeType:1,select:function(){
                throw new Error("Failed to suppress error thrown by select.");
            }}
            
            var actual=Record.Exception(function(){
                System.Web.Dom.Focus(targetNode,true);
            });
            
            Assert.Null(actual);
        }
        
        [Fact]
        function ReturnsFalseIfSelectThrowsError(){
            var targetNode={nodeType:1,select:function(){
                throw new Error("Failed to suppress error thrown by select.");
            }}
            
            var actual=System.Web.Dom.Focus(targetNode,true);
            
            Assert.False(actual);
        }        

        [Fact]
        function SuppressesErrorIfFocusIsNotAValidFunction(){
            var targetNode={nodeType:1,focus:{}}
            
            var actual=Record.Exception(function(){
                System.Web.Dom.Focus(targetNode);
            });
            
            Assert.Null(actual);
        }

        [Fact]
        function ReturnsFalseIfSelectIsNotAValidFunction(){
            var targetNode={nodeType:1,focus:{}};
            
            var actual=System.Web.Dom.Focus(targetNode);
            
            Assert.False(actual);
        }        

        [Fact]
        function SuppressesErrorThrownByFocus(){
            var targetNode={nodeType:1,focus:function(){
                throw new Error("Failed to suppress error thrown by focus.");
            }}
            
            var actual=Record.Exception(function(){
                System.Web.Dom.Focus(targetNode);
            });
            
            Assert.Null(actual);
        }

        [Fact]
        function ReturnsFalseIfFocusThrowsError(){
            var targetNode={nodeType:1,focus:function(){
                throw new Error("Failed to suppress error thrown by focus.");
            }}
            
            var actual=System.Web.Dom.Focus(targetNode);
            
            Assert.False(actual);
        }        
    }
    
    [Fixture]
    function GetContent(){
        [Fact]
        function ThrowsIfNodeIsOmitted(){
            var expected="System.Web.Dom.GetContent: 'node' must be a valid Node.";
            
            var actual=Record.Exception(function(){
                System.Web.Dom.GetContent();
            });
            
            Assert.Equal(expected,actual);
        }
 
        [Fact]
        function ThrowsIfNodeIsUndefined(){
            var expected="System.Web.Dom.GetContent: 'node' must be a valid Node.";
            
            var actual=Record.Exception(function(){
                System.Web.Dom.GetContent(undefined);
            });
            
            Assert.Equal(expected,actual);
        }
        [Fact]
        function ThrowsIfNodeIsNull(){
            var expected="System.Web.Dom.GetContent: 'node' must be a valid Node.";
            
            var actual=Record.Exception(function(){
                System.Web.Dom.GetContent(null);
            });
            
            Assert.Equal(expected,actual);
        }
        
        [Fact]
        function ThrowsIfNodeDoesNotImplementNodeType(){
            var expected="System.Web.Dom.GetContent: 'node' must be a valid Node.";
            
            var actual=Record.Exception(function(){
                System.Web.Dom.GetContent({});
            });
            
            Assert.Equal(expected,actual);
        }

        [Fact]
        function ThrowsIfNodeTypeIsBooleanFalse(){
            var expected="System.Web.Dom.GetContent: 'node' must be a valid Node.";
            
            var actual=Record.Exception(function(){
                System.Web.Dom.GetContent({nodeType:false});
            });
            
            Assert.Equal(expected,actual);
        }

        [Fact]
        function ThrowsIfNodeTypeIsNumberZero(){
            var expected="System.Web.Dom.GetContent: 'node' must be a valid Node.";
            
            var actual=Record.Exception(function(){
                System.Web.Dom.GetContent({nodeType:0});
            });
            
            Assert.Equal(expected,actual);
        }

        [Fact]
        function ThrowsIfNodeTypeIsStringEmpty(){
            var expected="System.Web.Dom.GetContent: 'node' must be a valid Node.";
            
            var actual=Record.Exception(function(){
                System.Web.Dom.GetContent({nodeType:''});
            });
            
            Assert.Equal(expected,actual);
        }
        
        [Fact]
        function DoesNotThrowIfNodeImplementsNodeType(){
            var actual=Record.Exception(function(){
                System.Web.Dom.GetContent({nodeType:1});
            });
            
            Assert.Null(actual);
        }
        
        [Fact]
        function ReturnsUndefinedIfNodeInnerHTMLIsNotSpecified(){
            var actual=System.Web.Dom.GetContent({nodeType:1});
        
            Assert.Undefined(actual);
        }

        [Fact]
        function ReturnsUndefinedIfNodeInnerHTMLIsUndefined(){
            var actual=System.Web.Dom.GetContent({nodeType:1,innerHTML:undefined});
        
            Assert.Undefined(actual);
        }

        [Fact]
        function ReturnsNullIfNodeInnerHTMLIsNull(){
            var actual=System.Web.Dom.GetContent({nodeType:1,innerHTML:null});
        
            Assert.Null(actual);
        }

        [Fact]
        function ReturnsNodeInnerHTML(){
            var expected="expected";
            
            var actual=System.Web.Dom.GetContent({nodeType:1,innerHTML:expected});
        
            Assert.Equal(expected,actual);
        }
    }
    
    [Fixture]
    function GetAttribute(){
        [Fact]
        function ThrowsIfNodeIsOmitted(){
            var expected="System.Web.Dom.GetAttribute: 'node' must be a valid Node.";
            
            var actual=Record.Exception(function(){
                System.Web.Dom.GetAttribute();
            });
            
            Assert.Equal(expected,actual);
        }
 
        [Fact]
        function ThrowsIfNodeIsUndefined(){
            var expected="System.Web.Dom.GetAttribute: 'node' must be a valid Node.";
            
            var actual=Record.Exception(function(){
                System.Web.Dom.GetAttribute(undefined);
            });
            
            Assert.Equal(expected,actual);
        }
        [Fact]
        function ThrowsIfNodeIsNull(){
            var expected="System.Web.Dom.GetAttribute: 'node' must be a valid Node.";
            
            var actual=Record.Exception(function(){
                System.Web.Dom.GetAttribute(null);
            });
            
            Assert.Equal(expected,actual);
        }
        
        [Fact]
        function ThrowsIfNodeDoesNotImplementNodeType(){
            var expected="System.Web.Dom.GetAttribute: 'node' must be a valid Node.";
            
            var actual=Record.Exception(function(){
                System.Web.Dom.GetAttribute({});
            });
            
            Assert.Equal(expected,actual);
        }

        [Fact]
        function DoesNotThrowIfNodeImplementsNodeType(){
            var actual=Record.Exception(function(){
                System.Web.Dom.GetAttribute({nodeType:1,attributes:[]});
            });
            
            Assert.Null(actual);
        }

        [Fact]
        function ReturnsNodeValueFromAttributesCollection(){
            var expected="expected";
            var targetExpected="expected";
            var targetAttributes={};
            targetAttributes[targetExpected]={nodeValue:expected};

            var actual=System.Web.Dom.GetAttribute({nodeType:1,attributes:targetAttributes},targetExpected);
            
            Assert.Equal(expected,actual);
        }

        [Fact]
        function ReturnsNodeValueFromGetAttributeMethod(){
            var expected="expected";
            var targetExpected="expected";
            var targetAttributes={};
            targetAttributes[targetExpected]={nodeValue:expected};

            var actual=System.Web.Dom.GetAttribute({nodeType:1,getAttribute:function(name){
                if(name==targetExpected)return expected;
                return null;
            }},targetExpected);
            
            Assert.Equal(expected,actual);
        }
    }
    
    [Fixture]
    function GetElement(){
        [Fact]
        function DoesNotThrowIfOwnerDocumentIsOmitted(){
            var cleanup=false;
            if(typeof(document)=="undefined"){
                document={};
                cleanup=true;
            }
            var targetGetElement=document.getElementById;
            document.getElementById=function(){};
            
            var actual=Record.Exception(function(){
                System.Web.Dom.GetElement("");
            });
            document.getElementById=targetGetElement;
            if(cleanup)delete document;
        
            Assert.Null(actual);
        }

        [Fact]
        function DoesNotThrowIfOwnerDocumentIsUndefined(){
            var cleanup=false;
            if(typeof(document)=="undefined"){
                document={};
                cleanup=true;
            }
            var targetGetElement=document.getElementById;
            document.getElementById=function(){};
            
            var actual=Record.Exception(function(){
                System.Web.Dom.GetElement("",undefined);
            });
            document.getElementById=targetGetElement;
            if(cleanup)delete document;
        
            Assert.Null(actual);
        }

        [Fact]
        function DoesNotThrowIfOwnerDocumentIsNull(){
            var cleanup=false;
            if(typeof(document)=="undefined"){
                document={};
                cleanup=true;
            }
            var targetGetElement=document.getElementById;
            document.getElementById=function(){};
            
            var actual=Record.Exception(function(){
                System.Web.Dom.GetElement("",null);
            });
            document.getElementById=targetGetElement;
            if(cleanup)delete document;
        
            Assert.Null(actual);
        }

        [Fact]
        function ThrowsIfOwnerDocumentDoesNotImplementGetElement(){            
            var expected="System.Web.Dom.GetElement: 'ownerDocument' does not implement method 'getElementById()'.";

            var actual=Record.Exception(function(){
                System.Web.Dom.GetElement("",{});
            });
        
            Assert.Equal(expected,actual);
        }

        [Fact]
        function CallsGetElementOnOwnerDocument(){
            var targetDocument={getElementById:function(){
                actual=true;
            }};
            var actual=false;
            
            System.Web.Dom.GetElement("",targetDocument);
        
            Assert.True(actual);
        }

        [Fact]
        function PassesIdToGetElementOnOwnerDocument(){
            var targetDocument={getElementById:function(targetId){
                actual=targetId;
            }};
            var expected="expected";
            var actual=null;
            
            System.Web.Dom.GetElement(expected,targetDocument);
        
            Assert.Equal(expected,actual);
        }

        [Fact]
        function CallsGetElementOnGlobalDocument(){
            var cleanup=false;
            if(typeof(document)=="undefined"){
                document={};
                cleanup=true;
            }
            var targetGetElement=document.getElementById;
            document.getElementById=function(){
                actual=true;
            };
            var actual=false;
            
            System.Web.Dom.GetElement("");
            document.getElementById=targetGetElement;
            if(cleanup)delete document;
        
            Assert.True(actual);
        }

        [Fact]
        function PassesIdToGetElementOnGlobalDocument(){
            var cleanup=false;
            if(typeof(document)=="undefined"){
                document={};
                cleanup=true;
            }
            var targetGetElement=document.getElementById;
            document.getElementById=function(targetId){
                actual=targetId;
            };
            var expected="expected";
            var actual=null;
            
            System.Web.Dom.GetElement(expected);
            document.getElementById=targetGetElement;
            if(cleanup)delete document;
        
            Assert.Equal(expected,actual);
        }
    }
    
    [Fixture]
    function GetText(){
        [Fact]
        function ThrowsIfNodeIsOmitted(){
            var expected="System.Web.Dom.GetText: 'node' must be a valid Node.";
            
            var actual=Record.Exception(function(){
                System.Web.Dom.GetText();
            });
            
            Assert.Equal(expected,actual);
        }
 
        [Fact]
        function ThrowsIfNodeIsUndefined(){
            var expected="System.Web.Dom.GetText: 'node' must be a valid Node.";
            
            var actual=Record.Exception(function(){
                System.Web.Dom.GetText(undefined);
            });
            
            Assert.Equal(expected,actual);
        }
        [Fact]
        function ThrowsIfNodeIsNull(){
            var expected="System.Web.Dom.GetText: 'node' must be a valid Node.";
            
            var actual=Record.Exception(function(){
                System.Web.Dom.GetText(null);
            });
            
            Assert.Equal(expected,actual);
        }
        
        [Fact]
        function ThrowsIfNodeDoesNotImplementNodeType(){
            var expected="System.Web.Dom.GetText: 'node' must be a valid Node.";
            
            var actual=Record.Exception(function(){
                System.Web.Dom.GetText({});
            });
            
            Assert.Equal(expected,actual);
        }

        [Fact]
        function ThrowsIfNodeTypeIsBooleanFalse(){
            var expected="System.Web.Dom.GetText: 'node' must be a valid Node.";
            
            var actual=Record.Exception(function(){
                System.Web.Dom.GetText({nodeType:false});
            });
            
            Assert.Equal(expected,actual);
        }

        [Fact]
        function ThrowsIfNodeTypeIsNumberZero(){
            var expected="System.Web.Dom.GetText: 'node' must be a valid Node.";
            
            var actual=Record.Exception(function(){
                System.Web.Dom.GetText({nodeType:0});
            });
            
            Assert.Equal(expected,actual);
        }

        [Fact]
        function ThrowsIfNodeTypeIsStringEmpty(){
            var expected="System.Web.Dom.GetText: 'node' must be a valid Node.";
            
            var actual=Record.Exception(function(){
                System.Web.Dom.GetText({nodeType:''});
            });
            
            Assert.Equal(expected,actual);
        }
        
        [Fact]
        function DoesNotThrowIfNodeImplementsNodeType(){
            var actual=Record.Exception(function(){
                System.Web.Dom.GetText({nodeType:1});
            });
            
            Assert.Null(actual);
        }
        
        [Fact]
        function ReturnsUndefinedIfTextContentAndInnerTextAreNotSpecified(){
            var actual=System.Web.Dom.GetText({nodeType:1});

            Assert.Undefined(actual);
        }

        [Fact]
        function ReturnsUndefinedIfTextContentIsNotSpecifiedAndInnerTextIsUndefined(){
            var actual=System.Web.Dom.GetText({nodeType:1,innerText:undefined});

            Assert.Undefined(actual);
        }

        [Fact]
        function ReturnsNullIfTextContentIsNotSpecifiedAndInnerTextIsNull(){
            var actual=System.Web.Dom.GetText({nodeType:1,innerText:null});

            Assert.Null(actual);
        }

        [Fact]
        function ReturnsInnerTextIfTextContentIsNotSpecified(){
            var expected="expected";
            
            var actual=System.Web.Dom.GetText({nodeType:1,innerText:expected});

            Assert.Equal(expected,actual);
        }

        [Fact]
        function ReturnsTextContentIfInnerTextIsNotSpecified(){
            var expected="expected";
            
            var actual=System.Web.Dom.GetText({nodeType:1,textContent:expected});

            Assert.Equal(expected,actual);
        }

        [Fact]
        function ReturnsTextContentOverInnerTextIfBothAreSpecified(){
            var expected="expected";
            
            var actual=System.Web.Dom.GetText({nodeType:1,textContent:expected,innerText:"innerText"});

            Assert.Equal(expected,actual);
        }
    }
    
    [Fixture]
    function Remove(){
        [Fact]
        function ThrowsIfNodeIsOmitted(){
            var expected="System.Web.Dom.Remove: 'node' must be a valid Node.";
            
            var actual=Record.Exception(function(){
                System.Web.Dom.Remove();
            });
            
            Assert.Equal(expected,actual);
        }
 
        [Fact]
        function ThrowsIfNodeIsUndefined(){
            var expected="System.Web.Dom.Remove: 'node' must be a valid Node.";
            
            var actual=Record.Exception(function(){
                System.Web.Dom.Remove(undefined);
            });
            
            Assert.Equal(expected,actual);
        }
        [Fact]
        function ThrowsIfNodeIsNull(){
            var expected="System.Web.Dom.Remove: 'node' must be a valid Node.";
            
            var actual=Record.Exception(function(){
                System.Web.Dom.Remove(null);
            });
            
            Assert.Equal(expected,actual);
        }
        
        [Fact]
        function ThrowsIfNodeDoesNotImplementNodeType(){
            var expected="System.Web.Dom.Remove: 'node' must be a valid Node.";
            
            var actual=Record.Exception(function(){
                System.Web.Dom.Remove({});
            });
            
            Assert.Equal(expected,actual);
        }

        [Fact]
        function ThrowsIfNodeTypeIsBooleanFalse(){
            var expected="System.Web.Dom.Remove: 'node' must be a valid Node.";
            
            var actual=Record.Exception(function(){
                System.Web.Dom.Remove({nodeType:false});
            });
            
            Assert.Equal(expected,actual);
        }

        [Fact]
        function ThrowsIfNodeTypeIsNumberZero(){
            var expected="System.Web.Dom.Remove: 'node' must be a valid Node.";
            
            var actual=Record.Exception(function(){
                System.Web.Dom.Remove({nodeType:0});
            });
            
            Assert.Equal(expected,actual);
        }

        [Fact]
        function ThrowsIfNodeTypeIsStringEmpty(){
            var expected="System.Web.Dom.Remove: 'node' must be a valid Node.";
            
            var actual=Record.Exception(function(){
                System.Web.Dom.Remove({nodeType:''});
            });
            
            Assert.Equal(expected,actual);
        }
        
        [Fact]
        function DoesNotThrowIfNodeImplementsNodeType(){
            var actual=Record.Exception(function(){
                System.Web.Dom.Remove({nodeType:1});
            });
            
            Assert.Null(actual);
        }
        
        [Fact]
        function CallsRemoveChildOnParentNode(){
            var targetNode={nodeType:1,parentNode:{removeChild:function(){
                actual=true;
            }}}
            var actual=false;
            
            System.Web.Dom.Remove(targetNode);
            
            Assert.True(actual);
        }

        [Fact]
        function PassesNodeToRemoveChildOnParentNode(){
            var expected={nodeType:1,parentNode:{removeChild:function(targetChild){
                actual=targetChild;
            }}}
            var actual=null;
            
            System.Web.Dom.Remove(expected);
            
            Assert.Equal(expected,actual);
        }
    }
    
    [Fixture,Skip("Not Implemented Yet.")]
    function RemoveAttribute(){
        [Fact]
        function ThrowsNotImplementedException(){
            Assert.Fail();
        }
    }
    
    [Fixture]
    function SelectNodes(){
        [Fact]
        function ThrowsIfMatchesIsOmitted(){
            var expected="System.Web.Dom.SelectNodes: 'matches' must be a valid Object.";
            
            var actual=Record.Exception(function(){
                System.Web.Dom.SelectNodes();
            });
            
            Assert.Equal(expected,actual);
        }

        [Fact]
        function ThrowsIfMatchesIsUndefined(){
            var expected="System.Web.Dom.SelectNodes: 'matches' must be a valid Object.";
            
            var actual=Record.Exception(function(){
                System.Web.Dom.SelectNodes(undefined);
            });
            
            Assert.Equal(expected,actual);
        }

        [Fact]
        function ThrowsIfMatchesIsNull(){
            var expected="System.Web.Dom.SelectNodes: 'matches' must be a valid Object.";
            
            var actual=Record.Exception(function(){
                System.Web.Dom.SelectNodes(null);
            });
            
            Assert.Equal(expected,actual);
        }

        [Fact]
        function ThrowsIfMatchesIsOmitted(){
            var expected="System.Web.Dom.SelectNodes: 'matches' must be a valid Object.";
            
            var actual=Record.Exception(function(){
                System.Web.Dom.SelectNodes();
            });
            
            Assert.Equal(expected,actual);
        }

        [Fact]
        function DoesNotThrowIfNumberIsOmitted(){
            var actual=Record.Exception(function(){
                Mocks.GetMock(Object.Global(),"document",{})(function(){
                    System.Web.Dom.SelectNodes(null,{});
                });
            });
            
            Assert.Null(actual);        
        }

        [Fact]
        function ReturnsEmptyArrayIfElementHasChildNodesIsNotImplemented(){
            var actual=System.Web.Dom.SelectNodes({},{});
            
            Assert.Empty(actual);
        }
        
        [Fact]
        function CallsObjectContainsToTestMatchOnChildNode(){
            var targetContains=Object.Contains;
            Object.Contains=function(){
                actual=true;
            }
            var actual=false;
        
            System.Web.Dom.SelectNodes({hasChildNodes:true,childNodes:[{}]},{});
            Object.Contains=targetContains;
            
            Assert.True(actual);
        }

        [Fact]
        function PassesMatchObjectToObjectContains(){
            var targetContains=Object.Contains;
            Object.Contains=function(targetExpected){
                actual=targetExpected;
            }
            var expected={expected:"expected"};
            var actual=null;
        
            System.Web.Dom.SelectNodes({hasChildNodes:true,childNodes:[{}]},expected);
            Object.Contains=targetContains;
            
            Assert.Equal(expected,actual);
        }

        [Fact]
        function PassesChildNodeToObjectContains(){
            var targetContains=Object.Contains;
            Object.Contains=function(targetMatch,targetExpected){
                actual=targetExpected;
            }
            var expected={expected:"expected"};
            var actual=null;
        
            System.Web.Dom.SelectNodes({hasChildNodes:true,childNodes:[expected]},{});
            Object.Contains=targetContains;
            
            Assert.Equal(expected,actual);
        }

        [Fact]
        function DoesNotAddChildNodeToResultIfObjectContainsReturnsFalse(){
            var targetContains=Object.Contains;
            Object.Contains=function(targetMatch,targetExpected){
                return false;
            }
            var expected=[{expected:"expected"}];

            var actual=System.Web.Dom.SelectNodes({hasChildNodes:true,childNodes:expected},{});
            Object.Contains=targetContains;
            
            Assert.Empty(actual);
        }
        
        [Fact]
        function AddsChildNodeToResultIfObjectContainsReturnsTrue(){
            var targetContains=Object.Contains;
            Object.Contains=function(targetMatch,targetExpected){
                return true;
            }
            var expected=[{expected:"expected"}];

            var actual=System.Web.Dom.SelectNodes({hasChildNodes:true,childNodes:expected},{});
            Object.Contains=targetContains;
            
            Assert.Equal(expected,actual);
        }

        [Fact]
        function AddsAllChildNodesToResultIfLimitIsOmitted(){
            var targetContains=Object.Contains;
            Object.Contains=function(targetMatch,targetExpected){
                return true;
            }
            var expected=[
                {expected1:"expected1"},
                {expected2:"expected2"},
                {expected3:"expected3"}
            ];

            var actual=System.Web.Dom.SelectNodes({hasChildNodes:true,childNodes:expected},{});
            Object.Contains=targetContains;
            
            Assert.Equal(expected,actual);
        }

        [Fact]
        function AddsAllChildNodesToResultIfLimitIsUndefined(){
            var targetContains=Object.Contains;
            Object.Contains=function(targetMatch,targetExpected){
                return true;
            }
            var expected=[
                {expected1:"expected1"},
                {expected2:"expected2"},
                {expected3:"expected3"}
            ];

            var actual=System.Web.Dom.SelectNodes({hasChildNodes:true,childNodes:expected},{},undefined);
            Object.Contains=targetContains;
            
            Assert.Equal(expected,actual);
        }

        [Fact]
        function AddsAllChildNodesToResultIfLimitIsNull(){
            var targetContains=Object.Contains;
            Object.Contains=function(targetMatch,targetExpected){
                return true;
            }
            var expected=[
                {expected1:"expected1"},
                {expected2:"expected2"},
                {expected3:"expected3"}
            ];

            var actual=System.Web.Dom.SelectNodes({hasChildNodes:true,childNodes:expected},{},null);
            Object.Contains=targetContains;
            
            Assert.Equal(expected,actual);
        }

        [Fact]
        function AddsAllChildNodesToResultIfLimitIsNegative(){
            var targetContains=Object.Contains;
            Object.Contains=function(targetMatch,targetExpected){
                return true;
            }
            var expected=[
                {expected1:"expected1"},
                {expected2:"expected2"},
                {expected3:"expected3"}
            ];

            var actual=System.Web.Dom.SelectNodes({hasChildNodes:true,childNodes:expected},{},-1);
            Object.Contains=targetContains;
            
            Assert.Equal(expected,actual);
        }

        [Fact]
        function AddsAllChildNodesToResultIfLimitIsZero(){
            var targetContains=Object.Contains;
            Object.Contains=function(targetMatch,targetExpected){
                return true;
            }
            var expected=[
                {expected1:"expected1"},
                {expected2:"expected2"},
                {expected3:"expected3"}
            ];

            var actual=System.Web.Dom.SelectNodes({hasChildNodes:true,childNodes:expected},{},0);
            Object.Contains=targetContains;
            
            Assert.Equal(expected,actual);
        }

        [Fact]
        function AddsAllChildNodesToResultIfLimitIsEqualToLengthOfChildNodes(){
            var targetContains=Object.Contains;
            Object.Contains=function(targetMatch,targetExpected){
                return true;
            }
            var expected=[
                {expected1:"expected1"},
                {expected2:"expected2"},
                {expected3:"expected3"}
            ];

            var actual=System.Web.Dom.SelectNodes({hasChildNodes:true,childNodes:expected},{},expected.length);
            Object.Contains=targetContains;
            
            Assert.Equal(expected,actual);
        }

        [Fact]
        function AddsAllChildNodesToResultIfLimitIsGreaterThanLengthOfChildNodes(){
            var targetContains=Object.Contains;
            Object.Contains=function(targetMatch,targetExpected){
                return true;
            }
            var expected=[
                {expected1:"expected1"},
                {expected2:"expected2"},
                {expected3:"expected3"}
            ];

            var actual=System.Web.Dom.SelectNodes({hasChildNodes:true,childNodes:expected},{},expected.length+1);
            Object.Contains=targetContains;
            
            Assert.Equal(expected,actual);
        }

        [Fact]
        function AddsFirstChildNodeToResultIfLimitIsOne(){
            var targetContains=Object.Contains;
            Object.Contains=function(targetMatch,targetExpected){
                return true;
            }
            var expected=[{expected1:"expected1"}];
            var targetChildNodes=expected.concat([
                {expected2:"expected2"},
                {expected3:"expected3"}
            ]);

            var actual=System.Web.Dom.SelectNodes({hasChildNodes:true,childNodes:targetChildNodes},{},1);
            Object.Contains=targetContains;
            
            Assert.Equal(expected,actual);
        }

        [Fact]
        function AddsChildNodesToResultUntilLimitIsReached(){
            var targetContains=Object.Contains;
            Object.Contains=function(targetMatch,targetExpected){
                return true;
            }
            var expected=[
                {expected1:"expected1"},
                {expected2:"expected2"},
                {expected3:"expected3"}
            ];
            var targetChildNodes=expected.concat([
                {expected4:"expected4"},
                {expected5:"expected5"}
            ]);

            var actual=System.Web.Dom.SelectNodes({hasChildNodes:true,childNodes:targetChildNodes},{},expected.length);
            Object.Contains=targetContains;
            
            Assert.Equal(expected,actual);
        }
        
        [Fact]
        function AddsNestedChildNodeToResultIfObjectContainsReturnsTrue(){
            var targetContains=Object.Contains;
            Object.Contains=function(targetMatch,targetExpected){
                return targetExpected==expected[0];
            }
            var expected=[{expected:"expected"}];

            var actual=System.Web.Dom.SelectNodes({hasChildNodes:true,childNodes:[{hasChildNodes:true,childNodes:expected}]},{});
            Object.Contains=targetContains;
            
            Assert.Equal(expected,actual);
        }

        [Fact]
        function DoesNotAddNestedChildNodeToResultIfObjectContainsReturnsFalse(){
            var targetContains=Object.Contains;
            Object.Contains=function(targetMatch,targetExpected){
                return false;
            }
            var expected=[{expected:"expected"}];

            var actual=System.Web.Dom.SelectNodes({hasChildNodes:true,childNodes:[{hasChildNodes:true,childNodes:expected}]},{});
            Object.Contains=targetContains;
            
            Assert.Empty(actual);
        }

        [Fact]
        function AddsAllNestedChildNodesToResultIfLimitIsOmitted(){
            var targetContains=Object.Contains;
            Object.Contains=function(targetMatch,targetExpected){
                return Array.Contains(expected,targetExpected);
            }
            var expected=[
                {expected1:"expected1"},
                {expected2:"expected2"},
                {expected3:"expected3"}
            ];

            var actual=System.Web.Dom.SelectNodes({hasChildNodes:true,childNodes:[{hasChildNodes:true,childNodes:expected}]},{});
            Object.Contains=targetContains;
            
            Assert.Equal(expected,actual);
        }

        [Fact]
        function AddsAllNestedChildNodesToResultIfLimitIsUndefined(){
            var targetContains=Object.Contains;
            Object.Contains=function(targetMatch,targetExpected){
                return Array.Contains(expected,targetExpected);
            }
            var expected=[
                {expected1:"expected1"},
                {expected2:"expected2"},
                {expected3:"expected3"}
            ];

            var actual=System.Web.Dom.SelectNodes({hasChildNodes:true,childNodes:[{hasChildNodes:true,childNodes:expected}]},{},undefined);
            Object.Contains=targetContains;
            
            Assert.Equal(expected,actual);
        }

        [Fact]
        function AddsAllNestedChildNodesToResultIfLimitIsNull(){
            var targetContains=Object.Contains;
            Object.Contains=function(targetMatch,targetExpected){
                return Array.Contains(expected,targetExpected);
            }
            var expected=[
                {expected1:"expected1"},
                {expected2:"expected2"},
                {expected3:"expected3"}
            ];

            var actual=System.Web.Dom.SelectNodes({hasChildNodes:true,childNodes:[{hasChildNodes:true,childNodes:expected}]},{},null);
            Object.Contains=targetContains;
            
            Assert.Equal(expected,actual);
        }

        [Fact]
        function AddsAllNestedChildNodesToResultIfLimitIsNegative(){
            var targetContains=Object.Contains;
            Object.Contains=function(targetMatch,targetExpected){
                return Array.Contains(expected,targetExpected);
            }
            var expected=[
                {expected1:"expected1"},
                {expected2:"expected2"},
                {expected3:"expected3"}
            ];

            var actual=System.Web.Dom.SelectNodes({hasChildNodes:true,childNodes:[{hasChildNodes:true,childNodes:expected}]},{},-1);
            Object.Contains=targetContains;
            
            Assert.Equal(expected,actual);
        }

        [Fact]
        function AddsAllNestedChildNodesToResultIfLimitIsZero(){
            var targetContains=Object.Contains;
            Object.Contains=function(targetMatch,targetExpected){
                return Array.Contains(expected,targetExpected);
            }
            var expected=[
                {expected1:"expected1"},
                {expected2:"expected2"},
                {expected3:"expected3"}
            ];

            var actual=System.Web.Dom.SelectNodes({hasChildNodes:true,childNodes:[{hasChildNodes:true,childNodes:expected}]},{},0);
            Object.Contains=targetContains;
            
            Assert.Equal(expected,actual);
        }

        [Fact]
        function AddsAllNestedChildNodesToResultIfLimitIsEqualToLengthOfChildNodes(){
            var targetContains=Object.Contains;
            Object.Contains=function(targetMatch,targetExpected){
                return Array.Contains(expected,targetExpected);
            }
            var expected=[
                {expected1:"expected1"},
                {expected2:"expected2"},
                {expected3:"expected3"}
            ];

            var actual=System.Web.Dom.SelectNodes({hasChildNodes:true,childNodes:[{hasChildNodes:true,childNodes:expected}]},{},expected.length);
            Object.Contains=targetContains;
            
            Assert.Equal(expected,actual);
        }

        [Fact]
        function AddsAllNestedChildNodesToResultIfLimitIsGreaterThanLengthOfChildNodes(){
            var targetContains=Object.Contains;
            Object.Contains=function(targetMatch,targetExpected){
                return Array.Contains(expected,targetExpected);
            }
            var expected=[
                {expected1:"expected1"},
                {expected2:"expected2"},
                {expected3:"expected3"}
            ];

            var actual=System.Web.Dom.SelectNodes({hasChildNodes:true,childNodes:[{hasChildNodes:true,childNodes:expected}]},{},expected.length+1);
            Object.Contains=targetContains;
            
            Assert.Equal(expected,actual);
        }

        [Fact]
        function AddsFirstNestedChildNodeToResultIfLimitIsOne(){
            var targetContains=Object.Contains;
            Object.Contains=function(targetMatch,targetExpected){
                return Array.Contains(expected,targetExpected);
            }
            var expected=[
                {expected1:"expected1"}
            ]
            var targetChildNodes=expected.concat([
                {expected2:"expected2"},
                {expected3:"expected3"}
            ]);

            var actual=System.Web.Dom.SelectNodes({hasChildNodes:true,childNodes:[{hasChildNodes:true,childNodes:targetChildNodes}]},{},1);
            Object.Contains=targetContains;
            
            Assert.Equal(expected,actual);
        }

        [Fact]
        function AddsNestedChildNodesToResultUntilLimitIsReached(){
            var targetContains=Object.Contains;
            Object.Contains=function(targetMatch,targetExpected){
                return Array.Contains(expected,targetExpected);
            }
            var expected=[
                {expected1:"expected1"},
                {expected2:"expected2"},
                {expected3:"expected3"}
            ];
            var targetChildNodes=expected.concat([
                {expected4:"expected4"},
                {expected5:"expected5"}
            ]);

            var actual=System.Web.Dom.SelectNodes({hasChildNodes:true,childNodes:[{hasChildNodes:true,childNodes:targetChildNodes}]},{},expected.length);
            Object.Contains=targetContains;
            
            Assert.Equal(expected,actual);
        }
        
        [Fact]
        function AddsAllSparselyNestedChildNodesIfLimitIsOmitted(){
            var targetContains=Object.Contains;
            Object.Contains=function(targetMatch,targetExpected){
                return Array.Contains(expected,targetExpected);
            }
            var expected=[
                {expected1:"expected1"},
                {expected2:"expected2"},
                {expected3:"expected3"}
            ];

            var targetChildNodes=[
                {hasChildNodes:true,childNodes:[expected[0]]},
                {hasChildNodes:true,childNodes:[expected[1]]},
                {hasChildNodes:true,childNodes:[expected[2]]}
            ];

            var actual=System.Web.Dom.SelectNodes({hasChildNodes:true,childNodes:targetChildNodes},{});
            Object.Contains=targetContains;
            
            Assert.Equal(expected,actual);
        }

        [Fact]
        function AddsAllSparselyNestedChildNodesIfLimitIsUndefined(){
            var targetContains=Object.Contains;
            Object.Contains=function(targetMatch,targetExpected){
                return Array.Contains(expected,targetExpected);
            }
            var expected=[
                {expected1:"expected1"},
                {expected2:"expected2"},
                {expected3:"expected3"}
            ];

            var targetChildNodes=[
                {hasChildNodes:true,childNodes:[expected[0]]},
                {hasChildNodes:true,childNodes:[expected[1]]},
                {hasChildNodes:true,childNodes:[expected[2]]}
            ];

            var actual=System.Web.Dom.SelectNodes({hasChildNodes:true,childNodes:targetChildNodes},{},undefined);
            Object.Contains=targetContains;
            
            Assert.Equal(expected,actual);
        }

        [Fact]
        function AddsAllSparselyNestedChildNodesIfLimitIsNull(){
            var targetContains=Object.Contains;
            Object.Contains=function(targetMatch,targetExpected){
                return Array.Contains(expected,targetExpected);
            }
            var expected=[
                {expected1:"expected1"},
                {expected2:"expected2"},
                {expected3:"expected3"}
            ];

            var targetChildNodes=[
                {hasChildNodes:true,childNodes:[expected[0]]},
                {hasChildNodes:true,childNodes:[expected[1]]},
                {hasChildNodes:true,childNodes:[expected[2]]}
            ];

            var actual=System.Web.Dom.SelectNodes({hasChildNodes:true,childNodes:targetChildNodes},{},null);
            Object.Contains=targetContains;
            
            Assert.Equal(expected,actual);
        }

        [Fact]
        function AddsAllSparselyNestedChildNodesIfLimitIsNegative(){
            var targetContains=Object.Contains;
            Object.Contains=function(targetMatch,targetExpected){
                return Array.Contains(expected,targetExpected);
            }
            var expected=[
                {expected1:"expected1"},
                {expected2:"expected2"},
                {expected3:"expected3"}
            ];

            var targetChildNodes=[
                {hasChildNodes:true,childNodes:[expected[0]]},
                {hasChildNodes:true,childNodes:[expected[1]]},
                {hasChildNodes:true,childNodes:[expected[2]]}
            ];

            var actual=System.Web.Dom.SelectNodes({hasChildNodes:true,childNodes:targetChildNodes},-1);
            Object.Contains=targetContains;

            Assert.Equal(expected,actual);
        }

        [Fact]
        function AddsAllSparselyNestedChildNodesIfLimitIsZero(){
            var targetContains=Object.Contains;
            Object.Contains=function(targetMatch,targetExpected){
                return Array.Contains(expected,targetExpected);
            }
            var expected=[
                {expected1:"expected1"},
                {expected2:"expected2"},
                {expected3:"expected3"}
            ];

            var targetChildNodes=[
                {hasChildNodes:true,childNodes:[expected[0]]},
                {hasChildNodes:true,childNodes:[expected[1]]},
                {hasChildNodes:true,childNodes:[expected[2]]}
            ];

            var actual=System.Web.Dom.SelectNodes({hasChildNodes:true,childNodes:targetChildNodes},{},0);
            Object.Contains=targetContains;
            
            Assert.Equal(expected,actual);
        }

        [Fact]
        function AddsFirstSparselyNestedChildNodeIfLimitIsOne(){
            var targetContains=Object.Contains;
            Object.Contains=function(targetMatch,targetExpected){
                return Array.Contains(expected,targetExpected);
            }
            var expected=[{expected1:"expected1"}];

            var targetChildNodes=[
                {hasChildNodes:true,childNodes:[expected[0]]},
                {hasChildNodes:true,childNodes:[{expected2:"expected2"}]},
                {hasChildNodes:true,childNodes:[{expected2:"expected2"}]}
            ];

            var actual=System.Web.Dom.SelectNodes({hasChildNodes:true,childNodes:targetChildNodes},{},1);
            Object.Contains=targetContains;
            
            Assert.Equal(expected,actual);
        }

        [Fact]
        function AddsSparselyNestedChildNodesToResultUntilLimitIsReached(){
            var targetContains=Object.Contains;
            Object.Contains=function(targetMatch,targetExpected){
                return Array.Contains(expected,targetExpected);
            }
            var expected=[
                {expected1:"expected1"},
                {expected2:"expected2"}
            ];

            var targetChildNodes=[
                {hasChildNodes:true,childNodes:[expected[0]]},
                {hasChildNodes:true,childNodes:[expected[1]]},
                {hasChildNodes:true,childNodes:[{expected3:"expected3"}]}
            ];

            var actual=System.Web.Dom.SelectNodes({hasChildNodes:true,childNodes:targetChildNodes},{},expected.length);
            Object.Contains=targetContains;
            
            Assert.Equal(expected,actual);
        }
    }
    
    [Fixture]
    function SelectSingleNode(){
        [Fact]
        function ThrowsIfMatchesIsOmitted(){
            var expected="System.Web.Dom.SelectSingleNode: 'matches' must be a valid Object.";
            
            var actual=Record.Exception(function(){
                System.Web.Dom.SelectSingleNode();
            });
            
            Assert.Equal(expected,actual);
        }

        [Fact]
        function ThrowsIfMatchesIsUndefined(){
            var expected="System.Web.Dom.SelectSingleNode: 'matches' must be a valid Object.";
            
            var actual=Record.Exception(function(){
                System.Web.Dom.SelectSingleNode(undefined);
            });
            
            Assert.Equal(expected,actual);
        }

        [Fact]
        function ThrowsIfMatchesIsNull(){
            var expected="System.Web.Dom.SelectSingleNode: 'matches' must be a valid Object.";
            
            var actual=Record.Exception(function(){
                System.Web.Dom.SelectSingleNode(null);
            });
            
            Assert.Equal(expected,actual);
        }

        [Fact]
        function ThrowsIfMatchesIsOmitted(){
            var expected="System.Web.Dom.SelectSingleNode: 'matches' must be a valid Object.";
            
            var actual=Record.Exception(function(){
                System.Web.Dom.SelectSingleNode();
            });
            
            Assert.Equal(expected,actual);
        }

        [Fact]
        function DoesNotThrowIfMatchesIsAValidObject(){
            var actual=Record.Exception(function(){
                Mocks.GetMock(Object.Global(),"document",{})(function(){
                    System.Web.Dom.SelectSingleNode(null,{});
                });
            });
            
            Assert.Null(actual);        
        }

        [Fact]
        function ReturnsNullIfElementHasChildNodesIsNotImplemented(){
            var actual=System.Web.Dom.SelectSingleNode({},{});
            
            Assert.Null(actual);
        }
        
        [Fact]
        function CallsObjectContainsToTestMatchOnChildNode(){
            var targetContains=Object.Contains;
            Object.Contains=function(){
                actual=true;
            }
            var actual=false;
        
            System.Web.Dom.SelectSingleNode({hasChildNodes:true,childNodes:[{}]},{});
            Object.Contains=targetContains;
            
            Assert.True(actual);
        }

        [Fact]
        function PassesMatchObjectToObjectContains(){
            var targetContains=Object.Contains;
            Object.Contains=function(targetExpected){
                actual=targetExpected;
            }
            var expected={expected:"expected"};
            var actual=null;
        
            System.Web.Dom.SelectSingleNode({hasChildNodes:true,childNodes:[{}]},expected);
            Object.Contains=targetContains;
            
            Assert.Equal(expected,actual);
        }

        [Fact]
        function PassesChildNodeToObjectContains(){
            var targetContains=Object.Contains;
            Object.Contains=function(targetMatch,targetExpected){
                actual=targetExpected;
            }
            var expected={expected:"expected"};
            var actual=null;
        
            System.Web.Dom.SelectSingleNode({hasChildNodes:true,childNodes:[expected]},{});
            Object.Contains=targetContains;
            
            Assert.Equal(expected,actual);
        }

        [Fact]
        function ReturnsNullIfObjectContainsReturnsFalse(){
            var targetContains=Object.Contains;
            Object.Contains=function(targetMatch,targetExpected){
                return false;
            }
            var targetChildNodes=[{expected:"expected"}];

            var actual=System.Web.Dom.SelectSingleNode({hasChildNodes:true,childNodes:targetChildNodes},{});
            Object.Contains=targetContains;
            
            Assert.Null(actual);
        }
        
        [Fact]
        function ReturnsChildNodeIfObjectContainsReturnsTrue(){
            var targetContains=Object.Contains;
            Object.Contains=function(targetMatch,targetExpected){
                return true;
            }
            var expected={expected:"expected"};

            var actual=System.Web.Dom.SelectSingleNode({hasChildNodes:true,childNodes:[expected]},{});
            Object.Contains=targetContains;
            
            Assert.Equal(expected,actual);
        }
        
        [Fact]
        function ReturnsNestedChildNodeIfObjectContainsReturnsTrue(){
            var targetContains=Object.Contains;
            Object.Contains=function(targetMatch,targetExpected){
                return expected==targetExpected;
            }
            var expected={expected:"expected"};

            var actual=System.Web.Dom.SelectSingleNode({hasChildNodes:true,childNodes:[{hasChildNodes:true,childNodes:[expected]}]},{});
            Object.Contains=targetContains;
            
            Assert.Equal(expected,actual);
        }
        
        [Fact]
        function ReturnsSparselyNestedChildNode(){
            var targetContains=Object.Contains;
            Object.Contains=function(targetMatch,targetExpected){
                return expected==targetExpected;
            }
            var expected={expected:"expected"};

            var targetChildNodes=[
                {hasChildNodes:true,childNodes:[{expected1:"expected1"}]},
                {hasChildNodes:true,childNodes:[expected]},
                {hasChildNodes:true,childNodes:[{expected2:"expected2"}]}
            ];

            var actual=System.Web.Dom.SelectSingleNode({hasChildNodes:true,childNodes:targetChildNodes},{});
            Object.Contains=targetContains;
            
            Assert.Equal(expected,actual);
        }
    }
    
    [Fixture,Skip("Not Implemented Yet.")]
    function SetAttribute(){
        [Fact]
        function ThrowsNotImplementedException(){
            
        }
    }
    
    [Fixture]
    function SetContent(){
        [Fact]
        function CallsClearContent(){
            var targetClearContent=System.Web.Dom.ClearContent;
            System.Web.Dom.ClearContent=function(){
                actual=true;
            }
            var actual=false;
            
            System.Web.Dom.SetContent({nodeType:1},'');
            System.Web.Dom.ClearContent=targetClearContent;
            
            Assert.True(actual);
        }

        [Fact]
        function PassesNodeToClearContent(){
            var targetClearContent=System.Web.Dom.ClearContent;
            System.Web.Dom.ClearContent=function(targetNode){
                actual=targetNode;
            }
            var expected={nodeType:1};
            var actual=false;
            
            System.Web.Dom.SetContent(expected,'');
            System.Web.Dom.ClearContent=targetClearContent;
            
            Assert.Equal(expected,actual);
        }

        [Fact]
        function CallsAppendContent(){
            var targetAppendContent=System.Web.Dom.AppendContent;
            System.Web.Dom.AppendContent=function(){
                actual=true;
            }
            var actual=false;
            
            System.Web.Dom.SetContent({nodeType:1},'');
            System.Web.Dom.AppendContent=targetAppendContent;
            
            Assert.True(actual);
        }

        [Fact]
        function PassesNodeToAppendContent(){
            var targetAppendContent=System.Web.Dom.AppendContent;
            System.Web.Dom.AppendContent=function(targetNode){
                actual=targetNode;
            }
            var expected={nodeType:1};
            var actual=false;
            
            System.Web.Dom.SetContent(expected,'');
            System.Web.Dom.AppendContent=targetAppendContent;
            
            Assert.Equal(expected,actual);
        }

        [Fact]
        function PassesMarkupToAppendContent(){
            var targetAppendContent=System.Web.Dom.AppendContent;
            System.Web.Dom.AppendContent=function(targetNode,targetMarkup){
                actual=targetMarkup;
            }
            var expected="expected";
            var actual=false;
            
            System.Web.Dom.SetContent({nodeType:1},expected);
            System.Web.Dom.AppendContent=targetAppendContent;
            
            Assert.Equal(expected,actual);
        }
    }
    
    [Fixture]
    function SetText(){
        [Fact]
        function CallsClearContent(){
            var targetClearContent=System.Web.Dom.ClearContent;
            System.Web.Dom.ClearContent=function(){
                actual=true;
            }
            var actual=false;
            var targetAppendText=System.Web.Dom.AppendText;
            System.Web.Dom.AppendText=function(){}
            
            System.Web.Dom.SetText({nodeType:1},'');
            System.Web.Dom.ClearContent=targetClearContent;
            System.Web.Dom.AppendText=targetAppendText;
            
            Assert.True(actual);
        }

        [Fact]
        function PassesNodeToClearContent(){
            var targetClearContent=System.Web.Dom.ClearContent;
            System.Web.Dom.ClearContent=function(targetNode){
                actual=targetNode;
            }
            var targetAppendText=System.Web.Dom.AppendText;
            System.Web.Dom.AppendText=function(){}
            var expected={nodeType:1};
            var actual=false;
            
            System.Web.Dom.SetText(expected,'');
            System.Web.Dom.ClearContent=targetClearContent;
            System.Web.Dom.AppendText=targetAppendText;
            
            Assert.Equal(expected,actual);
        }

        [Fact]
        function CallsAppendText(){
            var targetAppendText=System.Web.Dom.AppendText;
            System.Web.Dom.AppendText=function(){
                actual=true;
            }
            var actual=false;
            
            System.Web.Dom.SetText({nodeType:1},'');
            System.Web.Dom.AppendText=targetAppendText;
            
            Assert.True(actual);
        }

        [Fact]
        function PassesNodeToAppendText(){
            var targetAppendText=System.Web.Dom.AppendText;
            System.Web.Dom.AppendText=function(targetNode){
                actual=targetNode;
            }
            var expected={nodeType:1};
            var actual=false;
            
            System.Web.Dom.SetText(expected,'');
            System.Web.Dom.AppendText=targetAppendText;
            
            Assert.Equal(expected,actual);
        }

        [Fact]
        function PassesTextToAppendText(){
            var targetAppendText=System.Web.Dom.AppendText;
            System.Web.Dom.AppendText=function(targetNode,targetText){
                actual=targetText;
            }
            var expected="expected";
            var actual=false;
            
            System.Web.Dom.SetText({nodeType:1},expected);
            System.Web.Dom.AppendText=targetAppendText;
            
            Assert.Equal(expected,actual);
        }
    }    
}